#include "Shader.h"

/********************************************************/
/*                  Constructor                         */
/********************************************************/

Shader::Shader(GLenum type, const char *path)
{
    m_Type      =   type;
    m_FilePath  =   path;
    Init();
}

Shader::~Shader()
{
    glDeleteShader(m_Id); // Destruction du vertex shader
}

int Shader::Init()
{
    try
    {
        if(m_Type == GL_FRAGMENT_SHADER || m_Type == GL_VERTEX_SHADER)
        {
            m_Id = glCreateShader(m_Type);
        }

        if(Compile()==0)throw(1);

        return 1;
    }
    catch(int e)
    {
        if(e==0)
            printf("Wrong Shader Type \n");
        if(e==1)
        {
            printf("Compilation Error \n");
        }
        return 0;

    }
}


int Shader::Compile()
{
    GLchar *        code;
    int             fileLength;
    GLint           erreurCompilation(0), tailleErreur(0);

    try
    {
        // We start by opening the file storing the Shader source code
        std::ifstream   sourceFile(m_FilePath.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
        if(!sourceFile)  throw(0);                          // We must check if the File is correctly openned

        // We get back the file Length to know how many char we must extract from the file

        fileLength=sourceFile.tellg();
        sourceFile.seekg(0,std::ios::beg);

        code = new char[fileLength];
        sourceFile.read(code, fileLength);
        sourceFile.close();

        code[fileLength]='\0';

        // Shader Compilation

        std::string str = code;

        const char * cst = str.c_str();

        printf("%s \n", cst);

        glShaderSource(m_Id, 1, &cst, NULL);               // Set the Shader source code
        glCompileShader(m_Id);                              // Compile the shader

        // Compilation check

        glGetShaderiv(m_Id, GL_COMPILE_STATUS, &erreurCompilation);
       // glGetShaderiv(m_Id, )

        if(erreurCompilation != GL_TRUE)
        {

            glGetShaderiv(m_Id, GL_INFO_LOG_LENGTH, &tailleErreur);     // We get back the error string Length

            GLchar *erreur = new GLchar[tailleErreur + 1];
            erreur[tailleErreur] = '\0';

            glGetShaderInfoLog(m_Id, tailleErreur, &tailleErreur, erreur);  // We get back the error and put it inside the "error" char *

            // Affichage de l'erreuré

            std::cout << "Erreur de compilation du shader (" <<  m_Type << ") " << erreur << std::endl;

            // Free memory and return 0

            delete[] erreur;
        }
        return 1;
    }
    catch(int e)
    {
        if(e==0)
        {
            std::cout << "Erreur le fichier : " << m_FilePath << " n'existe pas" << std::endl;
            glDeleteShader(m_Id);
            return 0;
        }
        else if(e==1)
        {
            glGetShaderiv(m_Id, GL_INFO_LOG_LENGTH, &tailleErreur);     // We get back the error string Length

            GLchar *erreur = new GLchar[tailleErreur + 1];
            erreur[tailleErreur] = '\0';

            glGetShaderInfoLog(m_Id, tailleErreur, &tailleErreur, erreur);  // We get back the error and put it inside the "error" char *

            // Affichage de l'erreuré

            std::cout << "Erreur de compilation du shader (" <<  m_Type << ") " << erreur << std::endl;

            // Free memory and return 0

            delete[] erreur;
            return 0;
        }
    }
}



